package track

import (
	"errors"
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/gomodule/redigo/redis"
	"strconv"
	"time"
	"wx-api/adx-bid/config"
	"wx-api/adx-bid/models/bid/BidModel"
	"wx-api/adx-bid/services/clickhouse_tb"
	"wx-api/adx-bid/services/common"
	"wx-api/adx-bid/utils"
)

func HTrack(ty string, p, tprc string) {
	lg := HTrackPara(p)
	if lg == nil {
		return
	}
	//dddddd, _ := json.Marshal(lg)
	//fmt.Println("================")
	//fmt.Println(string(dddddd))
	//imp:曝光
	if ty == "imp" {
		HTrackImp(lg, tprc)
		return
	}
	isli := false
	//时效验证
	tt := time.Now().Unix()
	limit_hour := int64(2)
	if lg.DspPv > 0 {
		limit_hour = lg.DspPv
	}
	limit_hour = limit_hour * 60 * 60
	if (tt - lg.Timestamp) > limit_hour {
		//无效
		isli = true
	}
	//clk:点击
	if ty == "clk" {
		lg.Iclick = 0
		lg.Click = 1
		hkey := lg.GetDate() + "-" + lg.GetDspId()
		field := utils.MD5("clk" + lg.Syst + lg.GetAdxId() + lg.GetMediaId() + lg.GetSlotId() + lg.GetDspId() + "_" + lg.GetPlanId() + "_" + lg.GetPosId() + lg.GetBidid())
		if lg.GetSyst() == "3" {
			hkey = lg.GetDate() + "-" + lg.GetDateHour() + "-" + lg.GetAdvId()
			field = utils.MD5("clk" + lg.Syst + lg.GetAdxId() + lg.GetMediaId() + lg.GetSlotId() + lg.GetAdvId() + "_" + lg.GetPlanId() + "_" + lg.GetCreativeId() + lg.GetBidid())
		}
		if !HTrackGetRedis(hkey, field) {
			//无效
			isli = true
		}
		if isli {
			lg.Iclick = 1
			lg.Click = 0
		}
	}
	//其他上报不计价格
	lg.MediaRtbPrice = 0
	lg.MediaPrice = 0
	lg.DspRtbPrice = 0
	lg.DspPrice = 0
	lg.Cost = 0

	if ty != "clk" {
		switch ty {
		case "vds":
			lg.VideoStart = 1
		case "vde":
			lg.VideoEnd = 1
		case "sd":
			lg.DownloadStart = 1
		case "se":
			lg.DownloadEnd = 1
		case "si":
			lg.InstallStart = 1
		case "ei":
			lg.InstallEnd = 1
		case "ac":
			lg.Activation = 1
		case "sdp":
			lg.Deeplink = 1
		}
	}

	if lg.GetSyst() == "1" {
		clickhouse_tb.SspMsgSend(lg)
	} else if lg.GetSyst() == "2" {
		clickhouse_tb.AdxMsgSend(lg)
	} else if lg.GetSyst() == "3" {
		clickhouse_tb.DspMsgSend(lg)
	}
	//vds:视频播放开始
	//vde:视频播放结束
	//sd:开始下载
	//ed：结束下载
	//si：开始安装
	//ei：结束安装
	//ac：激活
	//dp：尝试吊起
	//sdp：吊起成功
	//fdp：吊起失败
}

func HTrackImp(lg *BidModel.LogMsg, tprc string) {
	//时效验证
	tt := time.Now().Unix()
	limit_hour := int64(2)
	if lg.DspPv > 0 {
		limit_hour = lg.DspPv
	}
	limit_hour = limit_hour * 60 * 60
	if (tt - lg.Timestamp) > limit_hour {
		//无效曝光
		lg.Ipv = 1
	} else {
		hkey := lg.GetDate() + "-" + lg.GetDateHour() + "-" + lg.GetDspId()
		field := utils.MD5("pv" + lg.Syst + lg.GetAdxId() + lg.GetMediaId() + lg.GetSlotId() + lg.GetDspId() + "_" + lg.GetPlanId() + "_" + lg.GetPosId() + lg.GetBidid())
		if lg.GetSyst() == "3" {
			hkey = lg.GetDate() + "-" + lg.GetDateHour() + "-" + lg.GetAdvId()
			field = utils.MD5("pv" + lg.Syst + lg.GetAdxId() + lg.GetMediaId() + lg.GetSlotId() + lg.GetAdvId() + "_" + lg.GetPlanId() + "_" + lg.GetCreativeId() + lg.GetBidid())
		}
		if !HTrackGetRedis(hkey, field) {
			//无效曝光
			lg.Ipv = 1
		}
	}
	if lg.Ipv == 0 {
		lg.Pv = 1
	}
	tmp_price := lg.GetMediaPrice()
	lg.MediaPrice = 0
	//价格解析
	tmpprice := DecPrice(lg.AdxId, tprc)
	if tmpprice > 0 {
		//媒体成交价校验
		if tmpprice <= tmp_price {
			lg.MediaPrice = tmpprice
		}
	}
	//dsp特殊处理
	if lg.GetSyst() == "3" {
		//dsp作为一价
		if lg.GetMediaPrice() == 0 { //下游未替换，使用自有价格作为计价
			lg.MediaPrice = lg.GetCost()
		}
	}
	if lg.GetSyst() == "1" {
		clickhouse_tb.SspMsgSend(lg)
	} else if lg.GetSyst() == "2" {
		clickhouse_tb.AdxMsgSend(lg)
	} else if lg.GetSyst() == "3" {
		clickhouse_tb.DspMsgSend(lg)
	}
	//dsp系统计费
	if lg.GetSyst() == "3" {
		//广告主
		go DspRtbAdSetRediaBudget("adv-"+lg.GetAdvId(), float64(lg.GetMediaPrice()))
		//计划
		go DspRtbAdSetRediaBudget("pl-"+lg.GetDate()+"-"+lg.GetPlanId(), float64(lg.GetMediaPrice()))
		//创意
		go DspRtbAdSetRediaBudget("ad-"+lg.GetCreativeId(), float64(lg.GetMediaPrice()))
	}
}

func DspRtbAdSetRediaBudget(key string, v float64) (float64, bool) {
	conn := config.DspAdvBudget.Get()
	if conn == nil {
		fmt.Println("DspRtbAdSetRediaBudget redis is nil")
		return 0, false
	}
	defer conn.Close()
	b, err := redis.Float64(conn.Do("INCRBYFLOAT", key, v))
	if err != nil && !errors.Is(err, redis.ErrNil) {
		fmt.Println("DspRtbAdSetRediaBudget redis get error:", err)
		return 0, false
	}
	//fmt.Println("key:", key)
	//fmt.Println("v:", v)
	//转化为元
	return (b / 100000), true
}
func DecPrice(adxid, tprc string) float32 {
	//默认明文
	decopr, _ := strconv.ParseFloat(tprc, 64)
	return float32(decopr)
}
func HTrackGetRedis(hkey, kfield string) bool {
	conn := config.AdxRedisTrack.Get()
	if conn == nil {
		fmt.Println("HTrackGetRedis track is nil")
		return true
	}
	defer conn.Close()
	tvs, err := redis.Int64(conn.Do("HINCRBY", hkey, kfield, 1))
	if err != nil {
		fmt.Println("HTrackGetRedis track error:", err.Error())
		return true
	}
	if tvs == 1 {
		return true
	}
	return false
}

func HTrackPara(p string) *BidModel.LogMsg {
	//解密
	bkmsg, err := common.MsgDecCBCDecrypt(p)
	if err != nil {
		fmt.Println(p)
		fmt.Println("HTrackPara aes error:" + err.Error())
		return nil
	}
	ret := &BidModel.LogMsg{}
	errp := proto.Unmarshal(bkmsg, ret)
	if errp != nil {
		fmt.Println(p)
		fmt.Println("HTrackPara proto error:" + errp.Error())
		return nil
	}
	if ret.GetDate() == "" || ret.GetDateHour() == "" || ret.GetTimestamp() == 0 || ret.GetBidid() == "" {
		return nil
	}
	return ret
}
